package com.mit.wx.wx;

import com.alibaba.fastjson.JSON;
import com.mit.wx.wx.dto.BinaryPart;
import com.mit.wx.wx.dto.MaterialDescribe;
import com.mit.wx.wx.dto.WxMaterialCreateResponse;
import com.mit.wx.wx.dto.WxNewsList;
import com.mit.wx.util.HttpUtil;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 2018/10/11 Create by 郭文梁
 * WxMaterialApi
 * 微信素材API封装组件
 *
 * @author 郭文梁
 * @date 2018/10/11
 */
public class WxMaterialApi {
    /**
     * 图片素材
     */
    public static final String IMAGE = "image";
    /**
     * 语音素材
     */
    public static final String VOICE = "voice";
    /**
     * 视频素材
     */
    public static final String VIDEO = "video";
    /**
     * 缩略图素材
     */
    public static final String THUMB = "thumb";
    /**
     * 图文消息素材
     */
    public static final String NEWS = "news";
    /**
     * 创建临时素材API地址
     */
    private static final String CREATE_TEMPORARY_MATERIAL_API = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s";
    private static final String CREATE_MATERIAL_API = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=%s&type=%s";
    private static final String LIST_MATERIAL_API = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=%s";

    /**
     * 创建临时素材
     *
     * @param accessToken accessToken
     * @param content     素材内容
     * @param type        素材类型
     * @return response
     */
    public static WxMaterialCreateResponse createTemporaryMaterial(String accessToken, byte[] content, String type) throws IOException {
        String url = String.format(CREATE_TEMPORARY_MATERIAL_API, accessToken, type);
        return postWithByteArray(url, content, WxMaterialCreateResponse.class);
    }

    /**
     * 创建永久素材
     *
     * @param accessToken accessToken
     * @param type        素材类型
     * @param content     素材内容
     * @param describe    素材描述
     * @return 返回消息 MediaId 和 url
     */

    public static WxMaterialCreateResponse createMaterial(String accessToken,
                                                          String type,
                                                          byte[] content,
                                                          String contentType,
                                                          String fileName,
                                                          MaterialDescribe describe) throws IOException {
        String url = String.format(CREATE_MATERIAL_API, accessToken, type);
        Map<String, BinaryPart> file = new HashMap<>(1);
        BinaryPart part = new BinaryPart();
        part.setContent(content);
        part.setFileName(fileName);
        part.setContentType(contentType);
        file.put("media", part);
        Map<String, String> form = new HashMap<>(1);
        form.put("description", JSON.toJSONString(describe));

        String resp = HttpUtil.postMultipartFile(url, file, form);

        return JSON.parseObject(resp, WxMaterialCreateResponse.class);
    }

    /**
     * 获取图文素材列表
     *
     * @param accessToken accessToken
     * @param offset      偏移量
     * @param count       获取数量
     * @return WxNewsList
     * @throws IOException IOException
     */
    public static WxNewsList getNewList(String accessToken, int offset, int count) throws IOException {
        String resp = getMaterialList(accessToken, NEWS, offset, count);
        return resp == null ? null : JSON.parseObject(resp, WxNewsList.class);
    }

    private static String getMaterialList(String accessToken, String type, int offset, int count) throws IOException {
        Map<String, Object> postBody = new HashMap<>(3);
        postBody.put("type", type);
        postBody.put("offset", offset);
        postBody.put("count", count);
        String body = JSON.toJSONString(postBody);

        String url = String.format(LIST_MATERIAL_API, accessToken);

        return HttpUtil.postWithStringBody(url, body, "UTF-8");
    }

    private static String postWithByteArray(String apiUrl, byte[] content) throws IOException {
        return HttpUtil.postWithByteArray(apiUrl, content);
    }

    private static <T> T postWithByteArray(String apiUrl, byte[] content, Class<T> responseType) throws IOException {
        return JSON.parseObject(postWithByteArray(apiUrl, content), responseType);
    }

    private static String postWithByteArray(String apiUrl, String accessToken, byte[] content) throws IOException {
        String url = String.format(apiUrl, accessToken);
        return postWithByteArray(url, content);
    }

    private static <T> T postWithByteArray(String apiUrl, String accessToken, byte[] content, Class<T> responseType) throws IOException {
        return JSON.parseObject(postWithByteArray(apiUrl, accessToken, content), responseType);
    }
}
